#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai

import sys
import re
from treesample import ExampleTreeBrowser

def get_cyg_tree():
    if len(sys.argv) < 3:
        print "Usage: %s" % sys.argv[0]
        sys.exit(2)

    nm_dict = {}
    nm_list = []
    nm_file = open(sys.argv[1], 'r')
    for nm_line in nm_file:
        nm_re = re.match('^(\w+) ([^dDWAU]) (\w+)', nm_line)
        if nm_re != None:
            #print "[%s]%s" % (nm_re.group(1), nm_re.group(3))
            nm_entry = [nm_re.group(1), nm_re.group(2), nm_re.group(3)]
            nm_dict[int(nm_re.group(1), 16)] = nm_re.group(3)
            nm_list.append(nm_entry)
            #if len(nm_dict) != len(nm_list):
            #    print "[%s]%s" % (nm_re.group(1), nm_re.group(3))
            #    break

    print "Number of Symbols %d" % len(nm_dict)
    print "Number of Symbols %d" % len(nm_list)
    #print nm_dict

    basetime = None # for dlt calculation
    cl_last = 0     # for dlt calculation
    cyg_stack = []  # for exe calculation
    cyg_root = {'symbol': 'root', 'name': 'root', 'children': [], 'type': '+'}
                    # for treeview representation
                    # a TREENODE {}
                    # {'name': symbol, 'children': TREENODE, 'type': [+-], 'timestamp': TIME}
    parent_node = cyg_root
    cyg_stack.append(cyg_root)
    cyg_file = open(sys.argv[2], 'r')
    for cyg_line in cyg_file:
        if re.match('^cygprofile*', cyg_line):
            print cyg_line
        cyg_re = re.match('(^[+-]) (\d+) (0x\w+) (0x\w+) (\d+)us', cyg_line)
        if cyg_re != None:
            cyg_addr = int(cyg_re.group(3), 16)
            if cyg_addr in nm_dict:
                cl_sym = nm_dict[cyg_addr]
            else:
                cl_sym = "0x%08x" % cyg_addr

            cl_type = cyg_re.group(1)
            cl_lev = int(cyg_re.group(2))
            cl_ret = cyg_re.group(4)
            cl_time = int(cyg_re.group(5))

            if basetime == None:
                cyg_root['timestamp'] = cl_time
                basetime = cl_time

            if cl_type == '+':
                print "%s%d%s %s(%s) -- %d ms dlt %d ms" % \
                    (("  " * cl_lev), cl_lev, cl_type, cl_sym, cl_ret, cl_time / 1000, (cl_time - cl_last) / 1000)
                cyg_node = {'symbol': cl_sym, 'children': [], \
                            'type': '+', 'timestamp': (cl_time - basetime)}
                cyg_node['name'] = "%s(%s)" % (cl_sym, cl_ret)
                #if cl_sym == 'APP_SHL_SWUpdate_CheckUSBDeviceWhenPowerOn':
                #    print cl_sym
                parent_node['children'].append(cyg_node)
                parent_node = cyg_node
                cyg_stack.append(cyg_node)
            else:
                parent_node = cyg_stack.pop()
                cl_enter = parent_node['timestamp']
                print "%s%d%s %s(%s) -- %d ms dlt %d ms exe %d ms" % \
                    (("  " * cl_lev), cl_lev, cl_type, cl_sym, \
                    cl_ret, cl_time / 1000, (cl_time - cl_last) / 1000, (cl_time - cl_enter - basetime) / 1000)
                cyg_node = {'symbol': cl_sym, 'children': [], \
                            'type': '-', 'end': True, 'timestamp': (cl_time - basetime)}
                cyg_node['name'] = "%s(%s)" % (cl_sym, cl_ret)
                parent_node['name'] = "%s -- (%sms)" % (parent_node['name'], (cl_time - cl_enter - basetime) / 1000)
                #if cl_sym == 'APP_SHL_SWUpdate_CheckUSBDeviceWhenPowerOn':
                #    print cl_sym
                parent_node = cyg_stack[-1]
                parent_node['children'].append(cyg_node)

            if basetime == None:
                cyg_root['timestamp'] = cl_time
                basetime = cl_time
            cl_last = cl_time

    #print cyg_root
    return cyg_root

def main():
    tree_root = get_cyg_tree()
    for ch in tree_root['children']:
        print ch['name']
    #print tree_root['children']
    ExampleTreeBrowser(tree_root).main()
    
if __name__ == "__main__":
    main()
